/*
 ************************************************************************************************
 *                                                                                              *
 *  OSA cooperative RTOS for Microchip PIC-controllers: PIC10/12/16/18/24/dsPIC                 *
 *                                                                                              *
 *  URL:        http://wiki.pic24.ru/doku.php/en/osa/ref/intro                                  *
 *              http://picosa.narod.ru                                                          *
 *                                                                                              *
 *----------------------------------------------------------------------------------------------*
 *                                                                                              *
 *  File:       osa_squeue.h                                                                    *
 *                                                                                              *
 *  Compilers:  HT-PICC STD                                                                     *
 *              HT-PICC18 STD                                                                   *
 *              Microchip C18                                                                   *
 *              Microchip C30                                                                   *
 *                                                                                              *
 *  Programmer: Timofeev Victor                                                                 *
 *              osa@pic24.ru, testerplus@mail.ru                                                *
 *                                                                                              *
 *  Definition: Services for work with queue of simple messages                                 *
 *                                                                                              *
 *                                                                                              *
 ************************************************************************************************
 */



/************************************************************************************************
 *                                                                                              *
 *                    Q U E U E   O F   S I M P L E    M E S S A G E S                          *
 *                                                                                              *
 ************************************************************************************************/

#ifdef OS_ENABLE_SQUEUE



    #if defined(OS_QUEUE_SQUEUE_IDENTICAL)

        // If size of pointer to message eq. to size of simple message then we
        // can use same functions for sending and getting messages.
        //
        #define _OS_SQueue_Send(pSQueue,SMsg)      _OS_Queue_Send((OST_QUEUE*)pSQueue, (OST_MSG)SMsg)
        #define _OS_IntSendSQueue(pSQueue,SMsg)   _OS_IntSendQueue((OST_QUEUE*)pSQueue, (OST_MSG)SMsg)
        #define _OS_GetSQueue(pSQueue)            _OS_GetQueue((OST_QUEUE*)pSQueue)

    #else

        extern void         _OS_SQueue_Send (OST_SQUEUE *pSQueue, OST_SMSG SMsg);
        extern OST_SMSG     _OS_GetSQueue (OST_SQUEUE *pSQueue);

    #endif

//------------------------------------------------------------------------------
// Create queue

#define OS_SQueue_Create(squeue, buffer, size)               \
    {                                                        \
        __OS_QUEUE_DI();                                     \
        (squeue).Q.cSize = size;                             \
        (squeue).Q.cBegin = 0;                               \
        (squeue).Q.cFilled = 0;                              \
        (squeue).pSMsg = (OST_SMSG*)buffer;                  \
        __OS_QUEUE_RI();                                     \
    }

//------------------------------------------------------------------------------
// Check for any message present in queue

#define OS_SQueue_Check(squeue)        ((squeue).Q.cFilled)

//------------------------------------------------------------------------------
// Check for queue is full

#define OS_SQueue_IsFull(squeue)       ((squeue).Q.cFilled == (squeue).Q.cSize)

//------------------------------------------------------------------------------
// Check for free room in queue

#define OS_SQueue_IsFree(squeue)       ((squeue).Q.cFilled ^ (squeue).Q.cSize)


//------------------------------------------------------------------------------
// Clear queue

#define OS_SQueue_Clear(squeue)        { (squeue).Q.cFilled = 0; }

//------------------------------------------------------------------------------
// Send message via queue. If queue full then wait for free place

#define OS_SQueue_Send(squeue, value)                                   \
    {                                                                   \
        if (OS_SQueue_IsFull(squeue))                                   \
            _OS_WAIT_EVENT(OS_SQueue_IsFree(squeue));                   \
        _OS_SQueue_Send(&(squeue), value);                              \
    }                                                                   \

//------------------------------------------------------------------------------
// Send message via queue. If queue full then wait for free place. Exit if timeout expired.

#define OS_SQueue_Send_TO(squeue, value, timeout)                       \
    {                                                                   \
        OS_Flags.bTimeout = 0;                                          \
        if (OS_SQueue_IsFull(squeue))                                   \
        {                                                               \
            _OS_WAIT_EVENT_TIMEOUT(OS_SQueue_IsFree(squeue), timeout);  \
        }                                                               \
        if (!OS_IsTimeout()) {                                          \
            _OS_SQueue_Send(&(squeue), value);                          \
        }                                                               \
    }

//------------------------------------------------------------------------------
// Send message via queue. If queue is full then most rearly message will be pushed out.

#define OS_SQueue_Send_Now(squeue, value)                               \
    {                                                                   \
        _OS_SQueue_Send(&(squeue), value);                              \
    }

//------------------------------------------------------------------------------
// Send message via queue from interrupt. If queue is full then most rearly message will be pushed out.
#if defined(OS_ENABLE_INT_QUEUE)

    extern void _OS_IntSendSQueue (OST_SQUEUE *pSQueue, OST_SMSG SMsg);

    #define OS_SQueue_Send_I(squeue, value)                             \
        {                                                               \
            _OS_IntSendSQueue(&(squeue), value);                        \
        }

#endif

//------------------------------------------------------------------------------
// Wait message from queue. After accepting message will be deleted from queue.

#define OS_SQueue_Wait(squeue, os_smsg_type_var)                        \
    {                                                                   \
        _OS_WAIT_EVENT(OS_SQueue_Check(squeue));                        \
        OS_SQueue_Accept(squeue,os_smsg_type_var);                      \
    }

//------------------------------------------------------------------------------
// Wait message from queue. After accepting message will be deleted from queue. Exit if timeout expired.

#define OS_SQueue_Wait_TO(squeue, os_smsg_type_var, timeout)            \
    {                                                                   \
        _OS_WAIT_EVENT_TIMEOUT(OS_SQueue_Check(squeue), timeout);       \
        if (!OS_IsTimeout())                                            \
        {                                                               \
            OS_SQueue_Accept(squeue,os_smsg_type_var);                  \
        }                                                               \
    }

//------------------------------------------------------------------------------
//
#define OS_SQueue_Accept(squeue,os_smsg_type_var)                       \
    {                                                                   \
        __OS_QUEUE_DI();                                                \
        os_smsg_type_var = _OS_GetSQueue(&(squeue));                    \
        __OS_QUEUE_RI();                                                \
    }






#endif




























